package comunicação.em.rede;
import java.io.*;                                                   //Pacote de entrada e saída
import java.net.*;                                                  //Pacote para sockets e threads

class Servidor extends Thread {                                     //Classe que permitirá o recebimento de mensagens, extende thread para o disparar o servidor
    private String Mensagem;                                        //Mensagem - Vetor que receberá os caracteres da mensagem
    private Conexão Caminho;                                        //Caminho - Contém dados vitais para o recebimento do pacote
    
    public Servidor(Conexão CaminhoR) {                              //Montador que permite recolher os dados da mensagem
        this.Caminho = CaminhoR;                                        //Seta o caimnho por onde a mensagem chegar
    }

    @Override
    public void run() {                                                                 //Dispara um "servidor" na thread que abrirá um canal ouvinte de mensagens
        byte[] DadosRecebidos;                                                          //Espaço para ser enviado no pacote de recebimento para recolher os bytes da mensagem
        byte[] LinhaTexto;                                                              //Espaço para recolher o mesmos bytes acima do pacote recebido
        boolean Decisão;                                                                //Decisão de quando "ouvir" uma mensagem
        DatagramSocket SocketRecebe = null;                                             //Referência para um socket (não recomendável criar a referência no try)
        
        try {                                                                           //Tenta executar o corpo de código
        while (true) {                                                                  //Laço infinito, ou seja, o servidor só irá parar no caso de haver um comando externo
               SocketRecebe = new DatagramSocket (Caminho.devolvePorta());              //Cria o socket de recebimento com a porta fornecida pela conexão
            
            Decisão = false;                                                                                //Torna a decisão falsa, ou seja, a decisão de parar não é tomada
            while (!Decisão){                                                                               //Enquanto a decisão for falsa o sevidor está ouvindo
                DadosRecebidos = new byte[255];                                                             //Cria um vetor para 255 caracteres, limite de recebimento 
                DatagramPacket PacoteRecebe = new DatagramPacket (DadosRecebidos, DadosRecebidos.length);   //Cria um pacote para recebimento de mensagens
              
                   SocketRecebe.receive(PacoteRecebe);                                                      //Manda sinal para o recebimento de um pacote
                   LinhaTexto = PacoteRecebe.getData();                                                     //Pega os dados do pacote que foi recebido
                   Mensagem = "";                                                                           //Zera a mensagem, evitar o acumulo das mesmas na mesma string
                   for (byte caracter : LinhaTexto){                                                        //Para todos os caracteres recebidos no apcote
                       if (caracter!=0) Mensagem += (char) caracter;                                        //Concatena na string de texto
                   }
                   if (Mensagem.isEmpty()==false) Caminho.RecebeMensagemTextArea(Mensagem);                 //Se a string não estiver vazia ou nula, chama método que mostra mensagem                                                                                                                         
               }
            }
        }
            catch (SocketException ex) {                                                //Execssão fornecida pela IDE
                    System.out.println("Ocorreu uma excessão no socket");               //Trata erro caso não consiga criar o socket
            }
	    catch (IOException ex) {                                                    //Excessão fornecida pela IDE
                    System.out.println("Ocorreu um erro de IO!!");                      //Trata erro de criação do pacote
            }
	    catch (Exception e){                                                        //Caso haja alguma excessão
                    System.out.println("Ocorreu um erro no recebimento da mensagem!!"); //Mostrar mensagem de erro para o usuário
                try {                                                                   //Tente executar
                    Thread.sleep(50);                                                   //Dar um tempo de recuperação para a thread
                } catch (InterruptedException ex) {                                     //Se a thread gerar uma intereupção
                    System.out.println("A thread não foi acessada!!");                  //Mostre
                }
                Decisão = true;                                                         //Decisão de erro é verdadeira, para o servidor
	    }        
    }
}
